package it.geosolutions.geoserver.rest.vgis;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.ogr.*;
import org.gdal.osr.SpatialReference;

import java.io.IOException;
import java.util.*;

/**
 * @author chenxw
 * @version 1.0
 * @date 2020/11/26 10:46
 */
public class GdalUtils {


    public static void main(String[] args) {
//        gdal.AllRegister();
//        System.out.println("args = " + args);
//        String jpgzipPath="E:\\data\\TW_2018_DDZD1_0.5.img";
//        getImgSpatailMetaInfo(jpgzipPath);
//        String imgPath="E:\\data\\TW_2021_DDZD1_0.5.jpg";
//        getImgSpatailMetaInfo(imgPath);
//        String imgPath="E:\\data\\TW_2021_DDZD1_0.5.zip";
//        try {
//            imgPath = ZipUtils.unZipAndGetFileBySuffix(imgPath, ".jpg");
//            getImgSpatailMetaInfo(imgPath);
//        }
//        catch (IOException ex){
//            System.out.println("解压失败");
//        }


    }
    //获取栅格影像元数据信息
    public static Map<String, Object> getImgSpatailMetaInfo(String imgPath) {

        Map<String, Object> rMap = new HashMap<>();
        try {
            gdal.AllRegister();
            Dataset pSrc = gdal.Open(imgPath);
            if (null != pSrc ) {
                String src_wkt = pSrc.GetProjectionRef();//获取源图像crs
                String coordName="";
                if(!src_wkt.equals("")){
                    String[] coordNameArray = src_wkt.split("\"");
                    coordName = coordNameArray[1];
                }
                else{
                    //针对jpg默认写4490
                    coordName="China Geodetic Coordinate System 2000";
                }

                int xsize = pSrc.getRasterXSize();
                int ysize = pSrc.getRasterYSize();
                double[] transform = pSrc.GetGeoTransform();
                if (null !=transform && transform.length > 0) {
                    for (double v : transform) {
                    }
                } else {
                    throw new IllegalStateException("解析影像文件异常");
                }
                rMap.put("coordName", coordName);
                rMap.put("xsize", xsize);
                rMap.put("ysize", ysize);
                rMap.put("transform", transform);
                pSrc.delete();
            } else {
                throw new IllegalStateException("未获取到数据信息:" + imgPath);
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalStateException(e.getMessage());
        } catch (Throwable t) {
            t.printStackTrace();
            throw new IllegalStateException(t.getMessage());
        } finally {
            gdal.GDALDestroyDriverManager();
        }
        return rMap;
    }

    //得到栅格影像的四至矩形范围
    public static List<Double> getEnvelopOfImg(String imgPath){
        List<Double> envlope = new ArrayList<Double>();
        Map<String, Object> map = GdalUtils.getImgSpatailMetaInfo(imgPath);
        String coordName = (String)map.get("coordName");
        int xsize = (Integer)map.get("xsize");
        int ysize = (Integer)map.get("ysize");
        double[] transform = (double[])map.get("transform");
        double v0 = transform[0];
        double v1 = transform[1];
        double v2 = transform[2];
        double v4 = transform[4];
        double v3 = transform[3];
        double v5 = transform[5];
        double minx=v0;
        double maxx=v0 + xsize * v1 + ysize * v2;
        double miny=v3 + xsize * v4 + ysize * v5;
        double maxy=v3;
        envlope.add(minx);
        envlope.add(miny);
        envlope.add(maxx);
        envlope.add(maxy);
        return envlope;
    }

    //得到矢量数据的元数据信息
    public static Map<String, Object> getShpSpatailMetaInfo(String filePath) {
        Map map = new HashMap();

        String src_wkt = "";
        try {
            //注册所有的驱动
            ogr.RegisterAll();
            // 为了支持中文路径，请添加下面这句代码
            gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            // 为了使属性表字段支持中文，请添加下面这句
            gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
            Driver driver = ogr.GetDriverByName("ESRI Shapefile");
//            filePath = StrUtils.setSlash(filePath);
            DataSource ds = driver.Open(filePath);
            if (Objects.isNull(ds)) {
                throw new IllegalStateException("DataSource isNull");
            }
            Layer layer0 = ds.GetLayerByIndex(0);
            //获取到shp的投影坐标系信息
            SpatialReference prosrs = layer0.GetSpatialRef();
            String tt = prosrs.GetAttrValue("AUTHORITY", 0) + prosrs.GetAttrValue("AUTHORITY", 1);
            //System.out.println(spatialReference);`1
//            System.out.println("getShpSapatilMetaInfo 空间参考坐标系：{}" ,
//                    prosrs.GetAttrValue("AUTHORITY", 0) + prosrs.GetAttrValue(
//                    "AUTHORITY", 1));

            src_wkt = prosrs.ExportToWkt();
            String[] coordNameArray = src_wkt.split("\"");
            String coordName = coordNameArray[1];
            map.put("code", 1);
            map.put("espg", prosrs.GetAttrValue("AUTHORITY", 1));
            map.put("coordname", coordName);
            Layer shpLayer = ds.GetLayer(0);
            double[] shpExtent = shpLayer.GetExtent();//minx,maxx,miny,maxy
            map.put("minx", shpExtent[0]);
            map.put("maxx", shpExtent[1]);
            map.put("miny", shpExtent[2]);
            map.put("maxy", shpExtent[3]);

            Feature feature = shpLayer.GetFeature(0);
            Geometry geo = feature.GetGeometryRef();
            int geoType = geo.GetGeometryType();
            map.put("geometryType", geoType == 1 ? "point" : geoType == 2 ? "line" : "polygon");

        } catch (Exception ex) {
//            log.error("getShpSpatailMetaInfo:{}", ex);
            map.put("code", 0);
            map.put("message", "获取矢量数据空间元数据信息失败----" + ex.getMessage());
        }

        return map;
    }

}